#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# File: data_download.py
# Date: 2024/7/4
# Author: 抖音、快手、视频号：东哥策略交易，微信：dongtrader
# Description: 东哥量化，带你走上量化之路。

import datetime
import logging
import os
import random
import sys
import time
from xtquant import xtconstant, xtdata
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount

import pandas as pd
import schedule
from tqdm import tqdm

import feather
from get_stock_data import extend_factor
from data_settings import *


if not os.path.exists(stockpath):
    print('没有找到股票数据文件夹，请核对路径是否正确，程序退出！')
    sys.exit(1)

# 交易错误的表名
error_name = 'stock_error'
# 设置日志配置
logging.basicConfig(filename=f'{tradepath}/early_sell.log', level=logging.INFO,
                    format='%(asctime)s - %(levelname)s - %(message)s')

debug = False

# 持仓股票数量
# stock_num = 30

# 限价交易列表
limitTrading = ['BH_trader']


def loggingseting(content, info='info'):
    if debug:
        print(f'{info}:{content}')

    if info == 'info':
        logging.info(content)
    elif info == 'error':
        logging.error(content)
    elif info == 'warning':
        logging.warning(content)


class MyXtQuantTraderCallback(XtQuantTraderCallback):
    def on_disconnected(self):
        """
        连接断开
        :return:
        """
        loggingseting("交易连接断开。")

    def on_stock_order(self, order):
        """
        委托回报推送
        :param order: XtOrder对象
        :return:
        """
        if order.order_type == 23:
            if order.order_status == 56:
                loggingseting(
                    f'股票{order.stock_code} 全部买入 成功！ 买入均价{round(order.traded_price, 2)}元，成交数量{order.traded_volume}股')
            elif order.order_status == 55:
                loggingseting(
                    f'股票{order.stock_code} 部分买入 成功！ 买入均价{round(order.traded_price, 2)}元，委托数量{order.order_volume}，成交数量{order.traded_volume}股')
        elif order.order_type == 24:
            if order.order_status == 56:
                loggingseting(
                    f'股票{order.stock_code} 全部卖出 成功！ 卖出均价{round(order.traded_price, 2)}元，成交数量{order.traded_volume}股')
            elif order.order_status == 55:
                loggingseting(
                    f'股票{order.stock_code} 部分卖出 成功！ 卖出均价{round(order.traded_price, 2)}元，委托数量{order.order_volume}，成交数量{order.traded_volume}股')


class _a():
    pass


def on_data(datas):
    for stock_code in datas:
        loggingseting(f"{stock_code}, {datas[stock_code]}")


def connect():
    # path改为自已的客户端安装目录下userdata_mini路径
    # path = r'D:\e海方舟-量化交易版模拟\userdata_mini'
    path = r'D:\e海方舟-量化交易版\userdata_mini'

    # session_id为会话编号，策略使用方对于不同的Python策略需要使用不同的会话编号
    session_id = random.randint(10224, 92024)
    xt_trader = XtQuantTrader(path, session_id)
    # 改成自己的普通账号
    acc = StockAccount('1388888888', account_type='STOCK')

    # 改成自己的两融账号
    # acc = StockAccount('18800038', account_type='CREDIT')

    # 创建交易回调类对象，并声明接收回调
    callback = MyXtQuantTraderCallback()
    xt_trader.register_callback(callback)
    # 启动交易线程
    xt_trader.start()
    # 建立交易连接，返回0表示连接成功
    connect_result = xt_trader.connect()
    loggingseting("交易连接成功！", 'warning') if connect_result == 0 else loggingseting("交易连接失败！", 'error')

    return xt_trader, acc


# 尾盘交易
def last_trade():
    # 查询交易策略的状态设置
    strategy_df = traderStrategy()
    state = strategy_df.loc[0, 'state']
    amount_std = strategy_df.loc[0, 'amount_std']
    strategy = strategy_df.loc[0, 'strategy']

    # 程序开始运行时间
    start_time = datetime.datetime.now()
    loggingseting(f'尾盘交易开始运行时间：{start_time}')

    # 连接账号
    xt_trader, acc = connect()

    # 查询持仓的股票号码，计算持仓股票数据，符合条件的卖出,
    positions = xt_trader.query_stock_positions(acc)
    if len(positions) != 0:
        for pos in positions:
            pos_code = pos.stock_code
            pos_vol = pos.volume
            # 查询当日所有的委托,并使用订单号对委托撤单。
            orders = xt_trader.query_stock_orders(acc)
            if len(orders) != 0:
                for o in orders:
                    if o.stock_code == pos_code:
                        if o.order_status == 56:
                            loggingseting(f'{o.stock_code}已经在盘中挂单中成交！')
                        else:
                            xt_trader.cancel_order_stock(acc, o.order_id)
                            loggingseting(f'{o.stock_code}已经撤单成功！')
                            if int(state) != 2:
                                temp_df = process_stockdata(pos_code)
                                if temp_df is not None:
                                    if temp_df[strategy][0] == -1:
                                        loggingseting(f'卖出股票{pos_code}，卖出数量{pos_vol}股')
                                        sell(xt_trader, acc, pos_code, pos_vol)
                            else:
                                loggingseting(f'卖出股票{pos_code}，卖出数量{pos_vol}股')
                                sell(xt_trader, acc, pos_code, pos_vol)

    # 买入流程，
    # 交易策略状态是否为可以正常买入，不为0则中止买入
    if int(state) != 0:
        # 程序结束运行时间
        end_time = datetime.datetime.now()
        loggingseting(f'尾盘交易程序运行时间：{end_time - start_time}s')
        return
    # 查询当前账户资金情况，如果现金不足以满足最低买入金额，则中止买入
    asset = xt_trader.query_stock_asset(acc)
    if asset:
        loggingseting(f'账号总资产{round(asset.total_asset, 2)}元,')
        loggingseting(f'当前持股市值{round(asset.market_value, 2)}元,')
        loggingseting(f'当前冻结金额{round(asset.frozen_cash, 2)}元,')
        loggingseting(f'目前可用现金{round(asset.cash, 2)}元')

    # 查询股票关注表,计算关注股票数据，符合条件的买入，
    code_list = []
    positions = xt_trader.query_stock_positions(acc)
    if len(positions) != 0:
        for pos in positions:
            pos_code = pos.stock_code
            pos_vol = pos.volume
            if pos_vol > 0:
                code_list.append(pos_code[:6])

    df = focusdata()
    reserve_code = []
    # 查询当前账户资金情况，如果现金不足以满足最低买入金额，则中止买入
    asset = xt_trader.query_stock_asset(acc)
    cash = round(asset.cash, 2)
    if cash < amount_std:
        loggingseting(f'帐户现金不足最低买入金额，中止买入')
    else:
        loggingseting(f'查询关注列表中的股票是否符合买入条件')
        for code in df['code'].tolist():
            if code in code_list:
                continue
            if int(code) >= 680000:
                continue
            print(f'查询{code}是否符合买入条件')
            temp_df = process_stockdata(code)
            if temp_df is not None:
                print(f"前高：{temp_df['be_high'][0]}, 现价{temp_df['close'][0]},买卖：{temp_df[strategy][0]}")
                if temp_df[strategy][0] == 1:
                    loggingseting(f'{code}符合买入条件')
                    # 查询当前账户资金情况，如果现金不足以满足最低买入金额，则中止买入
                    asset = xt_trader.query_stock_asset(acc)
                    cash = round(asset.cash, 2)
                    if cash < amount_std:
                        loggingseting(f'帐户现金不足最低买入金额，中止买入')
                        break
                    if strategy == 'BH_trader':
                        if temp_df['be_high'][0] + 0.02 < temp_df['close'][0]:
                            buy(xt_trader, acc, code, df, amount_std)
                        else:
                            reserve_code.append(code)
                    else:
                        buy(xt_trader, acc, code, df, amount_std)
    # 后备买入股票列表，后备股票为股价虽然突破，但与突破价十分接近，有可能尾盘回落突破不成功，放在收盘前最后再次确认
    if len(reserve_code) != 0:
        asset = xt_trader.query_stock_asset(acc)
        cash = round(asset.cash, 2)
        if cash > amount_std:
            # 定义两个时间点
            time1 = datetime.datetime.now()
            today = str(datetime.datetime.now().date())
            time2 = datetime.datetime(int(today[:4]), int(today[5:7]), int(today[8:]), 14, 56, 0)
            if time2 < time1:
                return
            # 计算时间差
            delta = time2 - time1
            # 等待时间14:56分再开启买入
            time.sleep(delta.seconds // 60 % 60 * 60 + delta.seconds % 60)
            for code in reserve_code:
                buy(xt_trader, acc, code, df, amount_std)
                asset = xt_trader.query_stock_asset(acc)
                cash = round(asset.cash, 2)
                if cash < amount_std:
                    loggingseting(f'帐户现金不足最低买入金额，中止买入')
                    break

    # 程序结束运行时间
    end_time = datetime.datetime.now()
    loggingseting(f'尾盘交易程序运行时间：{end_time - start_time}s')


def code_check(code_list=None):
    # 查询交易策略的状态设置
    strategy_df = traderStrategy()
    strategy = strategy_df.loc[0, 'strategy']
    tag = strategy[0:2]
    earnings = f'{tag}_earnings'
    success = f'{tag}_success'
    if code_list is None:
        df = focusdata()
        code_list = df['code'].tolist()
    print(len(code_list))
    for code in code_list:

        # print(f'查询{code}是否符合买入条件')
        temp_df = process_stockdata(code)
        if temp_df is not None:
            print(
                f"前高：{temp_df['be_high'][0]}, 现价{temp_df['close'][0]},平均利润{temp_df[earnings][0]}%,成功率{temp_df[success][0]}%")
            if temp_df[strategy][0] == 1:
                print(f'{code}符合买入条件')


# 收盘交易检查
def trader_check():
    st_time = datetime.datetime.now()
    loggingseting(f'收盘交易检查开始运行时间：{st_time}')
    # 程序开始运行时间
    start_time = time.time()

    # 连接账号
    xt_trader, acc = connect()

    try:
        error_df = feather.read_dataframe(f'{tradepath}/{error_name}.feather')
        errorlist = error_df['code'].tolist()
    except:
        error_df = pd.DataFrame(columns=['code'])
        feather.write_dataframe(error_df, f'{tradepath}/{error_name}.feather')
        errorlist = []

    # 查询当日所有的成交，已经卖出的股票，删除错误列表股票
    trades = xt_trader.query_stock_trades(acc)
    if len(errorlist) != 0:
        for trade in trades:
            xt_code = trade.stock_code
            if xt_code in errorlist and trade.order_type == 24:
                orders = xt_trader.query_stock_orders(acc)
                for o in orders:
                    if trade.order_id == o.order_id and o.order_status == 56:
                        errorlist.remove(xt_code)

    strategy_df = traderStrategy()
    strategy = strategy_df.loc[0, 'strategy']

    # 查询所有的持仓，如果错误则增加到错误列表
    positions = xt_trader.query_stock_positions(acc)
    if len(positions) != 0:
        print(f"目前持仓股票数量为:{len(positions)}个，分别为：")
        for pos in positions:
            xt_code = pos.stock_code
            print(f'{pos.stock_code}，持仓数量为：{pos.volume}')
            if pos.volume != 0:
                sql_code = xt_code[:6]
                temp_df = process_stockdata(sql_code)
                if temp_df is not None:
                    if temp_df[strategy][0] == 0 and temp_df[f'{strategy[:2]}_holddate'][0] == 0:
                        loggingseting(f'持仓股票{xt_code}，没有形成买点或没有在正确的持仓期间，卖出股票！', 'error')
                        errorlist.append(xt_code)

    # 删除重复code
    new_list = list(set(errorlist))
    if len(errorlist) > 0:
        loggingseting(f'买卖出现错误的股票有：{errorlist}！', 'error')
    # 连接数据库

    error_dict = {'code': new_list}
    error_df = pd.DataFrame(error_dict)
    feather.write_dataframe(error_df, f'{tradepath}/{error_name}.feather')

    # 程序结束运行时间
    end_time = time.time()
    loggingseting(f'收盘交易程序运行时间：{end_time - start_time}s')


# 关注表查询
def focusdata():
    # 读取交易策略
    strategy_df = traderStrategy()
    tag = strategy_df.loc[0, 'strategy'][:2]
    success = float(strategy_df.loc[0, 'success'])
    earnings = float(strategy_df.loc[0, 'earnings'])
    trades = float(strategy_df.loc[0, 'trades'])

    # 数据表
    table_name = f'stock_focus_{tag.lower()}'

    stock_df = feather.read_dataframe(f'{stockpath}/{table_name}.feather')
    # 构建筛选条件
    condition = (stock_df[f"{tag}_trades"] >= trades) & \
                (stock_df[f"{tag}_success"] >= success) & \
                (stock_df[f"{tag}_earnings"] >= earnings)

    # 应用条件筛选DataFrame
    stock_df = stock_df[condition]

    loggingseting('focus数据提取完毕。')

    # 将focus数据从高到低排列，先排盈利率，后排概率。
    df1 = stock_df.sort_values(by=f'{tag}_earnings', ascending=False)

    new_df = df1.sort_values(by=f'{tag}_success', ascending=False)

    # 输出排列后的focus数据的关键参数:['code','be_high','HT_earnings','HT_success']。

    # 重置索引
    new_df.reset_index(drop=True, inplace=True)

    return new_df


# 交易策略查询
def traderStrategy():
    """
    读取数据中的交易策略，
    交易策略包括交易状态state（0为正常交易，1为只卖不买，2为清仓或停止交易）；
    交易标准金额amount_std
    :return: strategy_df
    """
    # 数据表

    table_name = f'stock_strategy'

    strategy_df = pd.read_csv(f'./{table_name}.csv')

    loggingseting('读取交易策略完毕。')

    return strategy_df


def sell(xt_trader, acc, pos_code, pos_vol, price=0.0):
    try:
        # 直接最优价卖出
        if pos_code[7:] == 'SH':
            if price == 0.0:
                # 最优5档价卖出
                sell_id = xt_trader.order_stock(acc, pos_code, xtconstant.STOCK_SELL, pos_vol,
                                                xtconstant.MARKET_SH_CONVERT_5_CANCEL, 0)
                loggingseting(f"股票卖出委托，股票代码：{pos_code}，卖出数量：{pos_vol}，委托价格：最优五价。")
            else:
                # 普通指定价卖出
                sell_id = xt_trader.order_stock(acc, pos_code, xtconstant.STOCK_SELL, pos_vol,
                                                xtconstant.FIX_PRICE, price)
                loggingseting(f"股票卖出委托，股票代码：{pos_code}，卖出数量：{pos_vol}，委托价格：{price}。")

        else:
            if price == 0.0:
                # 最优5档价卖出
                sell_id = xt_trader.order_stock(acc, pos_code, xtconstant.STOCK_SELL, pos_vol,
                                                xtconstant.MARKET_SZ_CONVERT_5_CANCEL, 0)
                loggingseting(f"股票卖出委托，股票代码：{pos_code}，卖出数量：{pos_vol}，委托价格：最优五价。")
            else:
                # 普通指定价卖出
                sell_id = xt_trader.order_stock(acc, pos_code, xtconstant.STOCK_SELL, pos_vol,
                                                xtconstant.FIX_PRICE, price)
                loggingseting(f"股票卖出委托，股票代码：{pos_code}，卖出数量：{pos_vol}，委托价格：{price}。")

    except Exception as ex:
        loggingseting(f"数据出现错误：{ex}，请核查股票{pos_code}是否开盘？如需要卖出，请手动处理。", 'error')


def buy(xt_trader, acc, code, df, order_cash):
    close = float(df.loc[df['code'] == code, 'close'])

    if int(code) < 600000:
        xt_code = f"{code}.SZ"
    elif int(code) > 800000:
        xt_code = f"{code}.BJ"
    else:
        xt_code = f"{code}.SH"

    data = xtdata.get_full_tick([xt_code])
    price = data[xt_code]['lastPrice']

    if price / close < 1.06:
        volume = int(order_cash / 100 // price * 100)
        maxvolume = volume + 100

        if maxvolume * price <= order_cash * 1.2:
            if xt_code[7:] == 'SH':
                buy_id = xt_trader.order_stock(acc, xt_code, xtconstant.STOCK_BUY, maxvolume,
                                               xtconstant.MARKET_SH_CONVERT_5_CANCEL, 0)
            else:
                buy_id = xt_trader.order_stock(acc, xt_code, xtconstant.STOCK_BUY, maxvolume,
                                               xtconstant.MARKET_SZ_CONVERT_5_CANCEL, 0)
            loggingseting(f"股票买入委托，股票代码：{xt_code}，买入数量：{maxvolume}，委托价格：最优五价。")

        elif volume * price > order_cash * 0.8:
            if xt_code[7:] == 'SH':
                buy_id = xt_trader.order_stock(acc, xt_code, xtconstant.STOCK_BUY, volume,
                                               xtconstant.MARKET_SH_CONVERT_5_CANCEL, 0)
            else:
                buy_id = xt_trader.order_stock(acc, xt_code, xtconstant.STOCK_BUY, volume,
                                               xtconstant.MARKET_SZ_CONVERT_5_CANCEL, 0)
            loggingseting(f"股票买入委托，股票代码：{xt_code}，买入数量：{volume}，委托价格：最优五价。")

        else:
            loggingseting(f"股票{xt_code},资金利用不合理，不进行买入操作。")
    else:
        loggingseting(f"股票{xt_code}涨幅过大，不进行买入操作。")


def process_stockdata(code):
    """
    处理股票数据的函数
    """

    if len(code) == 6:
        if int(code) < 600000:
            xt_code = f"{code}.SZ"
        elif int(code) > 800000:
            xt_code = f"{code}.BJ"
        else:
            xt_code = f"{code}.SH"
    else:
        xt_code = code
    data = xtdata.get_full_tick([xt_code])
    if data == {}:
        return None
    sql_code = xt_code[:6]

    # 查询数据库数据
    try:
        old_df = feather.read_dataframe(f'{stockpath}/{sql_code}.feather')
    except:
        return None
    # 最新股票数据
    xt_date = datetime.date.today()
    xt_open = data[xt_code]['open']
    xt_high = data[xt_code]['high']
    xt_low = data[xt_code]['low']
    xt_close = data[xt_code]['lastPrice']
    xt_volume = data[xt_code]['volume']
    xt_amount = data[xt_code]['amount']
    stocklist = [sql_code, xt_date, xt_open, xt_high, xt_low, xt_close, xt_volume, xt_amount]
    old_len = len(old_df)
    # 创建DF文件修改列名
    new_df = pd.DataFrame([stocklist], columns=['code', 'date', 'open', 'high', 'low', 'close', 'volume', 'amount'])

    # 将数值数据转为float型，便于后续处理
    convert_list = ['open', 'high', 'low', 'close', 'volume', 'amount']
    new_df[convert_list] = new_df[convert_list].astype(float)

    # 并接新数据
    concat_df = pd.concat([old_df, new_df])
    # 重置索引
    concat_df.reset_index(drop=True, inplace=True)

    # 计算扩展因子
    temp_df = extend_factor(concat_df, old_len)[-1:]
    temp_df.reset_index(drop=True, inplace=True)

    return temp_df


# 早盘挂单
def early_sell():
    """
    每交易日定时任务，可设置为09:26启动
    :return: None
    """
    start_time = datetime.datetime.now()
    logging.info(f'早盘挂单开始运行时间：{start_time}')

    # 连接账号
    xt_trader, acc = connect()

    # 查询当日所有的持仓
    positions = xt_trader.query_stock_positions(acc)
    if len(positions) == 0:
        logging.info("没有持仓股票。")
        return

    # 读取交易策略
    strategy_df = traderStrategy()
    strategy = strategy_df.loc[0, 'strategy']

    try:
        error_df = feather.read_dataframe(f'{tradepath}/{error_name}.feather')
        errorlist = error_df['code'].tolist()
    except:
        print("没有错误股票。")
        error_df = pd.DataFrame(columns=['code'])
        feather.write_dataframe(error_df, f'{tradepath}/{error_name}.feather')

    selllist = []
    for pos in positions:
        pos_code = pos.stock_code
        pos_vol = pos.volume
        sql_code = pos_code[:6]

        # 策略为2，清仓；股票是否在错误列表里，如果是，则以最优5价卖出
        if (strategy_df.loc[0, 'state'] == 2) or (pos_code in errorlist):
            selllist.append([pos_code, pos_vol])


        # 股票是否在限价交易列表里，如果是，则以指定价卖出
        elif strategy_df.loc[0, 'strategy'] in limitTrading:
            # 数据表
            table_name = "stock_last"
            try:
                # 查询股票数据
                stock_df = feather.read_dataframe(f'{stockpath}/{table_name}.feather')
                stock_df = stock_df.loc[stock_df['code'] == sql_code]
                price = round(float(stock_df[f'{strategy[:2]}_buyprice'].values) * 1.04, 2)
            except Exception as ex:
                loggingseting(f"早盘挂单错误：{ex}，没有查询到{table_name}表中有股票{pos_code}的数据，请手动处理。", 'error')
                continue
            try:
                if price == 0.0:
                    sell(xt_trader, acc, pos_code, pos_vol)
                else:

                    close = float(stock_df['close'].values)
                    codetag = pos_code[:2]
                    if codetag in ['30', '68']:
                        proportion = 1.2
                    elif int(codetag) >= 80:
                        proportion = 1.3
                    else:
                        proportion = 1.1

                    if price < close * proportion:
                        # 普通卖出
                        loggingseting(f"早盘挂单：股票卖出委托，股票代码：{pos_code}，卖出数量：{pos_vol}，委托价格：{price}。")
                        sell(xt_trader, acc, pos_code, pos_vol, price=price)
                    else:
                        loggingseting(
                            f"股票代码：{pos_code}，挂单价格({price})超出股票涨停价：{round(price * proportion, 2)}.如需要卖出，请手动处理。",
                            'warning')

            except Exception as ex:
                loggingseting(f"早盘挂单错误：{ex}，请核查股票{pos_code}是否开盘？如需要卖出，请手动处理。", 'error')
    if len(selllist) > 0:
        # 定义两个时间点
        today = str(datetime.datetime.now().date())
        time1 = datetime.datetime(int(today[:4]), int(today[5:7]), int(today[8:]), 9, 30, 0)
        time2 = datetime.datetime.now()
        if time1 > time2:
            # 计算时间差
            delta = time1 - time2
            # 等待时间9:30分再开启买入
            time.sleep(delta.seconds // 60 % 60 * 60 + delta.seconds % 60)
        for code, vol in selllist:
            sell(xt_trader, acc, code, vol)


# 自动交易
def auto_trader():
    """
    每日交易任务启动
    :return: None
    """
    # 连接账号
    xt_trader, acc = connect()
    # 注册回调函数
    callback = MyXtQuantTraderCallback()
    xt_trader.register_callback(callback)
    # 启动交易线程
    # xt_trader.start()
    # 查询当前账户资金情况
    asset = xt_trader.query_stock_asset(acc)

    if asset:
        print(f'账号总资产{round(asset.total_asset, 2)}元,'
              f'当前持股市值{round(asset.market_value, 2)}元,'
              f'当前冻结金额{round(asset.frozen_cash, 2)}元,'
              f'目前可用现金{round(asset.cash, 2)}元')

    # 清空任务列表
    schedule.clear()

    # 早盘任务执行时间
    morning_time = '09:20:00'

    # 尾盘任务执行时间
    tail_time = '14:53:00'

    # 收盘任务执行时间
    close_time = '15:01:00'

    # 早盘定时启动任务
    schedule.every().monday.at(morning_time).do(early_sell)
    schedule.every().tuesday.at(morning_time).do(early_sell)
    schedule.every().wednesday.at(morning_time).do(early_sell)
    schedule.every().thursday.at(morning_time).do(early_sell)
    schedule.every().friday.at(morning_time).do(early_sell)

    # 尾盘定时启动任务
    schedule.every().monday.at(tail_time).do(last_trade)
    schedule.every().tuesday.at(tail_time).do(last_trade)
    schedule.every().wednesday.at(tail_time).do(last_trade)
    schedule.every().thursday.at(tail_time).do(last_trade)
    schedule.every().friday.at(tail_time).do(last_trade)

    # 收盘定时启动任务
    schedule.every().monday.at(close_time).do(trader_check)
    schedule.every().tuesday.at(close_time).do(trader_check)
    schedule.every().wednesday.at(close_time).do(trader_check)
    schedule.every().thursday.at(close_time).do(trader_check)
    schedule.every().friday.at(close_time).do(trader_check)

    # 循环等待任务执行
    t = 0
    while True:
        now = time.time()
        next_minute = (now // 60 + 1) * 60  # 下一个整分钟的秒数
        wait_time = next_minute - now  # 需要等待的时间（秒）
        time.sleep(wait_time)

        schedule.run_pending()
        print('.', end='')
        t += 1
        if t % 60 == 0:
            print('')
            print(f'{datetime.datetime.now()}')


# 求标准价
def amount_std():
    # (1000, 100000)就是每次交易的标准价。
    for standard_value in tqdm(range(1000, 100000)):
        # std = 15384 * 2
        lower_bound = standard_value * 0.8
        upper_bound = standard_value * 1.2

        chakan = []
        # (100, 10000)就是1~100元区间的股票整手价。
        for price in range(100, 10000):
            # price为整手价，100股/手
            cost = standard_value // (price)
            aom = cost * price
            if lower_bound <= aom <= upper_bound:
                pass
            else:
                cost = standard_value // (price) + 1
                aom = cost * price
                if lower_bound <= aom <= upper_bound:
                    pass
                else:
                    chakan.append(price)
        if chakan == []:
            print(f"找到最小值{standard_value}")
            break
    '''
    0.8~1.2（范围）
    1~10:1667，1~20:3334，1~30:5000，1~40:6667，1~50:8334
    1~60:10000，1~70:11667，1~80:13334，1~90:15000，1~100:16667
    '''


